/*
* // +-------------------------------------------------------------------------------------------------
* // |                 有你就好 [ 有节骨乃坚，无心品自端 ]     <http://encoding.wang>
* // +-------------------------------------------------------------------------------------------------
* // |                             独在异乡为异客         每逢佳节倍思亲
* // +-------------------------------------------------------------------------------------------------
* // |                 联系:   <707069100@qq.com>      <http://weibo.com/513778937>
* // +-------------------------------------------------------------------------------------------------
*/

// -----------------------------------------------------------------------------------------------------
// +----------------------------------------------------------------------------------------------------
// |                   ErYang出品 属于小极品          共同学习    共同进步
// +----------------------------------------------------------------------------------------------------
// -----------------------------------------------------------------------------------------------------


package wang.encoding.mroot.common.config


import org.apache.commons.codec.binary.Hex
import org.springframework.beans.factory.annotation.Autowired
import org.springframework.cache.annotation.EnableCaching
import org.springframework.stereotype.Component
import wang.encoding.mroot.common.constant.SecurityConst
import javax.crypto.Cipher
import javax.crypto.spec.IvParameterSpec
import javax.crypto.spec.SecretKeySpec


/**
 * AES对称加密和解密
 *
 * @author ErYang
 */
@Component
@EnableCaching
class AesManageConfiguration {


    companion object {

        /**
         * 字符编码
         */
        private const val CHARSET_NAME: String = "UTF-8"
        /**
         * AES加密
         */
        private const val AES: String = "AES"
        /**
         * 默认加密算法
         */
        private const val CIPHER_ALGORITHM: String = "AES/CBC/PKCS5Padding"
        /**
         * 初始向量
         * AES 为 16 bytes DES 为 8 bytes
         */
        //private const val VAl_AES: String = "d08724da546bb888"
        /**
         * 私钥
         * AES 固定格式为128/192/256 bits 即 16/24/32 bytes
         * DES固定格式为 128 bits 即8 bytes
         */
        //private const val ASE_KEY: String = "3d011361d08724da546bb888901d6930"

    }

    @Autowired
    private lateinit var securityConst: SecurityConst

    /**
     * 加密
     * 加密方式： AES128(CBC/PKCS5Padding) + Hex + 私钥
     *
     * @param data 待加密内容
     * @return  String 加密后的内容
     */
    fun encrypt(data: String): String {
        try {
            // IVParameterSpec
            val ivParameterSpec: IvParameterSpec = initIvParameterSpec()
            // 两个参数，第一个为私钥字节数组， 第二个为加密方式 AES或者DES
            val secretKeySpec: SecretKeySpec = initSecretKeySpec()
            // 实例化加密类，参数为加密方式，要写全
            // PKCS5Padding 比 PKCS7Padding 效率高 PKCS7Padding可支持 IOS 加解密
            val cipher: Cipher = initCipher()
            // 初始化 此方法可以采用三种方式，按加密算法要求来添加
            // （1）无第三个参数
            // （2）第三个参数为 SecureRandom random = new SecureRandom(); 中 random 对象随机数(AES不可采用这种方法)
            // （3）采用此代码中的 IVParameterSpec
            cipher.init(Cipher.ENCRYPT_MODE, secretKeySpec, ivParameterSpec)
            // 加密操作 返回加密后的字节数组 然后需要编码 主要编解码方式有 Base64 HEX
            val encryptedData: ByteArray = cipher.doFinal(data.toByteArray(charset(CHARSET_NAME)))
            return Hex.encodeHexString(encryptedData)
        } catch (e: Exception) {
            e.printStackTrace()
            return ""
        }
    }

    // -------------------------------------------------------------------------------------------------

    /**
     * 解密
     *
     * @param encrypted
     * @return
     */
    fun decrypt(encrypted: String): String {
        return try {
            val byteMi: ByteArray = Hex.decodeHex(encrypted)
            val ivParameterSpec: IvParameterSpec = initIvParameterSpec()
            val secretKeySpec: SecretKeySpec = initSecretKeySpec()
            val cipher: Cipher = initCipher()
            // 与加密时不同 MODE Cipher.DECRYPT_MODE
            cipher.init(Cipher.DECRYPT_MODE, secretKeySpec, ivParameterSpec)
            val decryptedData: ByteArray = cipher.doFinal(byteMi)
            String(decryptedData)
        } catch (e: Exception) {
            e.printStackTrace()
            ""
        }
    }

    // -------------------------------------------------------------------------------------------------

    /**
     * 初始化 IvParameterSpec
     */
    private fun initIvParameterSpec(): IvParameterSpec {
        return IvParameterSpec(securityConst.aesInit.toByteArray())
    }

    // -------------------------------------------------------------------------------------------------

    /**
     * 初始化 SecretKeySpec
     */
    private fun initSecretKeySpec(): SecretKeySpec {
        return SecretKeySpec(securityConst.aesKey.toByteArray(), AES)
    }

    // -------------------------------------------------------------------------------------------------

    /**
     * 初始化 Cipher
     */
    private fun initCipher(): Cipher {
        return Cipher.getInstance(CIPHER_ALGORITHM)
    }

    // -------------------------------------------------------------------------------------------------

}

// -----------------------------------------------------------------------------------------------------

// End AesManageConfiguration class

/* End of file AesManageConfiguration.kt */
/* Location: ./src/main/kotlin/wang/encoding/mroot/admin/common/config/AesManageConfiguration.kt */

// -----------------------------------------------------------------------------------------------------
// +----------------------------------------------------------------------------------------------------
// |                           ErYang出品 属于小极品  O(∩_∩)O~~   共同学习    共同进步
// +----------------------------------------------------------------------------------------------------
// -----------------------------------------------------------------------------------------------------
